package teabag;

import teabag.VariableManager.Variable;

public class Math {
	
	private static Math instance;
	private static VariableManager varMan;
	
	private Math()
	{
		
	}
	
	public static Math getInstance()
	{
		if( instance == null )
			instance = new Math();
		return instance;
	}
	
	public void add( String a, String b, String into )
	{
		if( varMan == null ) varMan = VariableManager.getInstance();
		if( !varMan.exists(into) )
			return;
		
		double dResult;
		int iResult; 
		
		String result;
		
		String sa = varMan.exists(a) ? varMan.getValue(a) : a;
		String sb = varMan.exists(b) ? varMan.getValue(b) : b;
		
		if( !_isNumber(sa) || !_isNumber(sb) )
			return;
		
		if( _isInt(sa) && _isInt(sb) )
		{
			iResult = Integer.parseInt(sa) + Integer.parseInt(sb);
			result = "" + iResult;
		}
		else
		{
			dResult = Double.parseDouble(sa) + Double.parseDouble(sb);
			result = "" + dResult;
		}
		
		varMan.setValue(into, result);
		
		Variable vResult = varMan.getVariable(into);
		System.out.println( "Set Variable '" + vResult.getName() + "' to '" + vResult.getValue() + "' with type '" + vResult.getType().toString() + "'" );
		
	}

	public void subtract(String a, String b, String into) {
		if( varMan == null ) varMan = VariableManager.getInstance();
		if( !varMan.exists(into) )
			return;
		
		double dResult;
		int iResult; 
		
		String result;
		
		String sa = varMan.exists(a) ? varMan.getValue(a) : a;
		String sb = varMan.exists(b) ? varMan.getValue(b) : b;
		
		if( !_isNumber(sa) || !_isNumber(sb) )
			return;
		
		if( _isInt(sa) && _isInt(sb) )
		{
			iResult = Integer.parseInt(sa) - Integer.parseInt(sb);
			result = "" + iResult;
		}
		else
		{
			dResult = Double.parseDouble(sa) - Double.parseDouble(sb);
			result = "" + dResult;
		}
		
		varMan.setValue(into, result);
		
		Variable vResult = varMan.getVariable(into);
		System.out.println( "Set Variable '" + vResult.getName() + "' to '" + vResult.getValue() + "' with type '" + vResult.getType().toString() + "'" );
		
	}

	public void multiply(String a, String b, String into) {
		if( varMan == null ) varMan = VariableManager.getInstance();
		if( !varMan.exists(into) )
			return;
		
		double dResult;
		int iResult; 
		
		String result;
		
		String sa = varMan.exists(a) ? varMan.getValue(a) : a;
		String sb = varMan.exists(b) ? varMan.getValue(b) : b;
		
		if( !_isNumber(sa) || !_isNumber(sb) )
			return;
		
		if( _isInt(sa) && _isInt(sb) )
		{
			iResult = Integer.parseInt(sa) * Integer.parseInt(sb);
			result = "" + iResult;
		}
		else
		{
			dResult = Double.parseDouble(sa) * Double.parseDouble(sb);
			result = "" + dResult;
		}
		
		varMan.setValue(into, result);
		
		Variable vResult = varMan.getVariable(into);
		System.out.println( "Set Variable '" + vResult.getName() + "' to '" + vResult.getValue() + "' with type '" + vResult.getType().toString() + "'" );
	}

	public void divide(String a, String b, String into) {
		if( varMan == null ) varMan = VariableManager.getInstance();
		if( !varMan.exists(into) )
			return;
		
		double dResult;
		
		String result;
		
		String sa = varMan.exists(a) ? varMan.getValue(a) : a;
		String sb = varMan.exists(b) ? varMan.getValue(b) : b;
		
		if( !_isNumber(sa) || !_isNumber(sb) )
			return;
		
		double db = Double.parseDouble(sb);
		if( db == 0.0 )
		{
			System.out.println( "Don't divide by zero kthxbye" );
			return;
		}
		
		dResult = Double.parseDouble(sa) / Double.parseDouble(sb);
		result = "" + dResult;	
		
		varMan.setValue(into, result);
		
		Variable vResult = varMan.getVariable(into);
		System.out.println( "Set Variable '" + vResult.getName() + "' to '" + vResult.getValue() + "' with type '" + vResult.getType().toString() + "'" );		
	}
	
	private boolean _isNumber( String value )
	{
		return ( _isInt(value) || _isDouble(value) );
	}
	
	protected Type findType( String value )
	{
		if( _isInt( value ) ) 
			return Type.INTEGER;
		if( _isDouble( value ) ) 
			return Type.DOUBLE;
		if( value.toLowerCase().equals("true") || value.toLowerCase().equals("false") )
			return Type.BOOLEAN;
		return Type.STRING;
	}
	
	protected boolean _isInt( String value )
	{
		try
		{
			Integer.parseInt( value );
			return true;
		}
		catch( NumberFormatException e)
		{
			return false;
		}
	}
	
	protected boolean _isDouble( String value )
	{
		try
		{
			Double.parseDouble( value );
			return true;
		}
		catch( NumberFormatException e)
		{
			return false;
		}
	}
}
